#include "cli_network.h"
#include "utils.h"

int initClientTcp(const char *server_ip, int server_port)
{
    struct sockaddr_in server_addr;
    int socket_fd;
    // 创建套接字
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0)
    {
        PRINT_ERROR("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);
    server_addr.sin_addr.s_addr = inet_addr(server_ip);

    // 连接到服务器
    if (connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        PRINT_ERROR("Connection failed");
        close(socket_fd);
        exit(EXIT_FAILURE);
    }

    PRINT_INFO("Connected to server: %s:%d", server_ip, server_port);
    return socket_fd;
}

void closeClientTcp(int socket_fd)
{
    if (socket_fd >= 0)
    {
        close(socket_fd);
        socket_fd = -1;
        PRINT_INFO("Closed client tcp");
    }
}

ssize_t sendAll(int sockfd, const void *buffer, size_t length, int flags)
{
    size_t total_sent = 0;
    const char *buf = (const char *)buffer;

    while (total_sent < length)
    {
        ssize_t bytes_sent = send(sockfd, buf + total_sent, length - total_sent, flags);
        if (bytes_sent == -1)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                return -1;
            }
        }
        total_sent += bytes_sent;
    }

    return total_sent;
}

ssize_t recvAll(int sockfd, void *buffer, size_t length, int flags)
{
    size_t total_received = 0;
    char *buf = (char *)buffer;

    while (total_received < length)
    {
        ssize_t bytes_received = recv(sockfd, buf + total_received, length - total_received, flags);
        if (bytes_received == -1)
        {
            if (errno == EINTR)
            {
                continue;
            }
            else
            {
                return -1;
            }
        }
        else if (bytes_received == 0)
        {
            break; // 连接关闭
        }
        total_received += bytes_received;
    }

    return total_received;
}

int connectTunnel(int socket_fd, Tunnel_t *tunnel)
{
    recvAll(socket_fd, tunnel, sizeof(Tunnel_t), 0);
    int tunnel_fd = initClientTcp(tunnel->ip, tunnel->port);
    PRINT_INFO("连接到服务器隧道-1 %s:%d", tunnel->ip, tunnel->port);
    return tunnel_fd;
}
